
/******************************************************************************/
/*----------------------------------Includes----------------------------------*/
/******************************************************************************/
#include "hb_Memory.h"

/******************************************************************************/
/*-----------------------------------Macros-----------------------------------*/
/******************************************************************************/
#define MEMORY_BUF_8B_NUM 0u
#define MEMORY_BUF_16B_NUM 0u
#define MEMORY_BUF_32B_NUM 0u
#define MEMORY_BUF_64B_NUM 8u //16u wq 2023/2/2
#define MEMORY_BUF_128B_NUM 4u //8u wq 2023/2/2
#define MEMORY_BUF_256B_NUM 4u //8u
#define MEMORY_BUF_512B_NUM 0u
#define MEMORY_BUF_1024B_NUM 0u
#define MEMORY_BUF_2048B_NUM 2u //4u
#define MEMORY_BUF_4096B_NUM 2u

#define MEMORY_BLOCK_TYPE_NUM 10u

#define MEMORY_BUF_TOTLE_NUB  \
  (MEMORY_BUF_8B_NUM +        \
   MEMORY_BUF_16B_NUM +       \
   MEMORY_BUF_32B_NUM +       \
   MEMORY_BUF_64B_NUM +       \
   MEMORY_BUF_128B_NUM +      \
   MEMORY_BUF_256B_NUM +      \
   MEMORY_BUF_512B_NUM +      \
   MEMORY_BUF_1024B_NUM +     \
   MEMORY_BUF_2048B_NUM +     \
   MEMORY_BUF_4096B_NUM)

#define MEMORY_BUF_TOTLE_SIZE     \
  (8 * MEMORY_BUF_8B_NUM +        \
   16 * MEMORY_BUF_16B_NUM +      \
   32 * MEMORY_BUF_32B_NUM +      \
   64 * MEMORY_BUF_64B_NUM +      \
   128 * MEMORY_BUF_128B_NUM +    \
   256 * MEMORY_BUF_256B_NUM +    \
   512 * MEMORY_BUF_512B_NUM +    \
   1024 * MEMORY_BUF_1024B_NUM +  \
   2048 * MEMORY_BUF_2048B_NUM +  \
   4096 * MEMORY_BUF_4096B_NUM)

/******************************************************************************/
/*------------------------------TYEP DEFINITION-------------------------------*/
/******************************************************************************/
typedef struct {
  uint32 size;
  boolean used;
} MemoryHeaderType;

typedef struct {
  MemoryHeaderType header;
  void* addr;
} MemoryPoolInfoType;

typedef struct {
  uint16 blockSize;
  uint16 blockNum;
} MemoryBlockInfoType;

/******************************************************************************/
/*------------------------------Global variables------------------------------*/
/******************************************************************************/

/******************************************************************************/
/*------------------------------Static variables------------------------------*/
/******************************************************************************/
static MemoryBlockInfoType Memory_blockInfo[MEMORY_BLOCK_TYPE_NUM] = {
    {8, MEMORY_BUF_8B_NUM},
    {16, MEMORY_BUF_16B_NUM},
    {32, MEMORY_BUF_32B_NUM},
    {64, MEMORY_BUF_64B_NUM},
    {128, MEMORY_BUF_128B_NUM},
    {256, MEMORY_BUF_256B_NUM},
    {512, MEMORY_BUF_512B_NUM},
    {1024, MEMORY_BUF_1024B_NUM},
    {2048, MEMORY_BUF_2048B_NUM},
    {4096, MEMORY_BUF_4096B_NUM}
};

static uint8 Memory_pool[MEMORY_BUF_TOTLE_SIZE] = {0};

static MemoryPoolInfoType Memory_poolInfo[MEMORY_BUF_TOTLE_NUB];

/******************************************************************************/
/*-------------------------Function Prototypes--------------------------------*/
/******************************************************************************/
static void hb_Memory_initPool(void* poolPtr, MemoryPoolInfoType* poolInfo,
                               MemoryBlockInfoType* blockInfo, uint16 blockNo);
/******************************************************************************/
/*-------------------------_Globale Function----------------------------------*/
/******************************************************************************/
void hb_Memory_Init(void) {
  hb_Memory_initPool(&Memory_pool[0], &Memory_poolInfo[0], &Memory_blockInfo[0],
                     MEMORY_BLOCK_TYPE_NUM);
}

void* hb_Memory_malloc(uint32 size) {
  uint16 i;
  void* addr = NULL_PTR;

  for (i = 0; i < MEMORY_BUF_TOTLE_NUB; i++) {
    if ((Memory_poolInfo[i].header.used == FALSE) &&
        (Memory_poolInfo[i].header.size >= size)) {
      Memory_poolInfo[i].header.used = TRUE;
      addr = Memory_poolInfo[i].addr;

      break;
    }
  }

  return addr;
}

void hb_Memory_free(void* addr) {
  uint16 i;

  for (i = 0; i < MEMORY_BUF_TOTLE_NUB; i++) {
    if (addr == Memory_poolInfo[i].addr) {
      Memory_poolInfo[i].header.used = FALSE;
      addr = NULL_PTR;
      break;
    }
  }
}

/******************************************************************************/
/*---------------------------Static Function----------------------------------*/
/******************************************************************************/
static void hb_Memory_initPool(void* poolPtr, MemoryPoolInfoType* poolInfo,
                               MemoryBlockInfoType* blockInfo, uint16 blockNo) {
	uint16 i;
	uint16 j;
	uint16 index;
	uint32 addr = 0;

	index = 0;
	addr = (uint32)poolPtr;

	for (i = 0; i < blockNo; i++) {
		for (j = 0; j < blockInfo[i].blockNum; j++) {
			poolInfo[index].header.used = FALSE;
			poolInfo[index].header.size = blockInfo[i].blockSize;
			poolInfo[index].addr = (void *)addr;
			index++;
			addr += blockInfo[i].blockSize;
		}
	}
	return;
}
